import { loadStripe, Stripe, StripeElements } from '@stripe/stripe-js';

// Replace with your Stripe publishable key
// @ts-expect-error - Vite env variable
const STRIPE_PUBLISHABLE_KEY = import.meta.env?.VITE_STRIPE_PUBLISHABLE_KEY || 'pk_test_YOUR_KEY_HERE';

let stripePromise: Promise<Stripe | null>;

/**
 * Get Stripe instance
 */
export const getStripe = () => {
  if (!stripePromise) {
    stripePromise = loadStripe(STRIPE_PUBLISHABLE_KEY);
  }
  return stripePromise;
};

/**
 * Create Payment Intent for adding funds
 */
export const createPaymentIntent = async (amount: number, currency: string = 'usd') => {
  try {
    // Call backend API endpoint
    const response = await fetch('http://localhost:3001/api/payment/create-intent', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        amount: Math.round(amount * 100), // Convert to cents
        currency,
      }),
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.error || 'Failed to create payment intent');
    }

    const data = await response.json();
    return {
      success: true,
      clientSecret: data.clientSecret,
      paymentIntentId: data.paymentIntentId,
    };
  } catch (error) {
    console.error('Create payment intent failed:', error);
    return { success: false, error };
  }
};

/**
 * Create Setup Intent for saving payment method
 */
export const createSetupIntent = async () => {
  try {
    // Call backend API endpoint
    const response = await fetch('http://localhost:3001/api/payment/create-setup-intent', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.error || 'Failed to create setup intent');
    }

    const data = await response.json();
    return {
      success: true,
      clientSecret: data.clientSecret,
      setupIntentId: data.setupIntentId,
    };
  } catch (error) {
    console.error('Create setup intent failed:', error);
    return { success: false, error };
  }
};

/**
 * Attach Payment Method to Customer
 */
export const attachPaymentMethod = async (paymentMethodId: string, customerId: string, setAsDefault: boolean = false) => {
  try {
    // Call backend API endpoint
    const response = await fetch('http://localhost:3001/api/payment/attach-method', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        paymentMethodId,
        customerId,
        setAsDefault,
      }),
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.error || 'Failed to attach payment method');
    }

    const data = await response.json();
    return {
      success: true,
      paymentMethod: data.paymentMethod,
    };
  } catch (error) {
    console.error('Attach payment method failed:', error);
    return { success: false, error };
  }
};

/**
 * Detach/Remove Payment Method
 */
export const detachPaymentMethod = async (paymentMethodId: string) => {
  try {
    // Call backend API endpoint
    const response = await fetch(`http://localhost:3001/api/payment/detach-method/${paymentMethodId}`, {
      method: 'DELETE',
      headers: {
        'Content-Type': 'application/json',
      },
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.error || 'Failed to detach payment method');
    }

    return { success: true };
  } catch (error) {
    console.error('Detach payment method failed:', error);
    return { success: false, error };
  }
};

/**
 * Get saved payment methods
 */
export const getPaymentMethods = async (customerId: string) => {
  try {
    // Call backend API endpoint
    const response = await fetch(`http://localhost:3001/api/payment/methods/${customerId}`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.error || 'Failed to get payment methods');
    }

    const data = await response.json();
    return {
      success: true,
      paymentMethods: data.methods,
    };
  } catch (error) {
    console.error('Get payment methods failed:', error);
    return { success: false, error };
  }
};

/**
 * Process payment with saved payment method
 */
export const processPayment = async (paymentMethodId: string, amount: number, currency: string = 'usd') => {
  try {
    // TODO: Replace with your actual API endpoint
    const response = await fetch('/api/process-payment', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        paymentMethodId,
        amount: Math.round(amount * 100), // Convert to cents
        currency,
      }),
    });

    if (!response.ok) {
      throw new Error('Failed to process payment');
    }

    const data = await response.json();
    return {
      success: true,
      paymentIntent: data.paymentIntent,
    };
  } catch (error) {
    console.error('Process payment failed:', error);
    return { success: false, error };
  }
};

/**
 * Confirm Payment Intent
 */
export const confirmPayment = async (
  stripe: Stripe,
  elements: StripeElements,
  clientSecret: string,
  returnUrl?: string
) => {
  try {
    // Submit the form to validate before confirming payment
    const { error: submitError } = await elements.submit();
    
    if (submitError) {
      return { success: false, error: submitError.message };
    }

    const { error, paymentIntent } = await stripe.confirmPayment({
      elements,
      clientSecret,
      confirmParams: {
        return_url: returnUrl || window.location.origin + '/dashboard/billing',
      },
      redirect: 'if_required',
    });

    if (error) {
      return { success: false, error: error.message };
    }

    return {
      success: true,
      paymentIntent,
    };
  } catch (error) {
    console.error('Confirm payment failed:', error);
    return { success: false, error };
  }
};

/**
 * Confirm Setup Intent (for saving payment method)
 */
export const confirmSetup = async (
  stripe: Stripe,
  elements: StripeElements,
  clientSecret: string,
  returnUrl?: string
) => {
  try {
    // Submit the form to validate before confirming setup
    const { error: submitError } = await elements.submit();
    
    if (submitError) {
      return { success: false, error: submitError.message };
    }

    const { error, setupIntent } = await stripe.confirmSetup({
      elements,
      clientSecret,
      confirmParams: {
        return_url: returnUrl || window.location.origin + '/dashboard/billing',
      },
      redirect: 'if_required',
    });

    if (error) {
      return { success: false, error: error.message };
    }

    return {
      success: true,
      setupIntent,
      paymentMethodId: setupIntent?.payment_method,
    };
  } catch (error) {
    console.error('Confirm setup failed:', error);
    return { success: false, error };
  }
};

export const stripeService = {
  getStripe,
  createPaymentIntent,
  createSetupIntent,
  attachPaymentMethod,
  detachPaymentMethod,
  getPaymentMethods,
  processPayment,
  confirmPayment,
  confirmSetup,
};
